package com.xiaoshuidi.cloud.module.contract.service.contract.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xiaoshuidi.cloud.framework.common.pojo.PageResult;
import com.xiaoshuidi.cloud.framework.common.util.json.JsonUtils;
import com.xiaoshuidi.cloud.module.contract.controller.admin.contract.vo.ContractRoomStatusQueryReqVO;
import com.xiaoshuidi.cloud.module.contract.controller.admin.contract.vo.company.CompanyContractStatusListRespVO;
import com.xiaoshuidi.cloud.module.contract.controller.admin.contract.vo.customerCompany.*;
import com.xiaoshuidi.cloud.module.contract.convert.contract.CustomerCompanyConvert;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.bill.RentOrderDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.ContractRoomDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.contract.CustomerCompanyDO;
import com.xiaoshuidi.cloud.module.contract.dal.dataobject.roommeta.ContractRoommateDO;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.bill.RentOrderMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.ContractRoomMapper;
import com.xiaoshuidi.cloud.module.contract.dal.mysql.contract.CustomerCompanyMapper;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderPayStatusEnum;
import com.xiaoshuidi.cloud.module.contract.enums.bill.OrderTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.CompanyContractOrderShareTypeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.ContractNodeEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.ContractStatusEnum;
import com.xiaoshuidi.cloud.module.contract.enums.contract.RoommateTypeEnum;
import com.xiaoshuidi.cloud.module.contract.service.contract.CompanyContractService;
import com.xiaoshuidi.cloud.module.contract.service.contract.ContractRoomService;
import com.xiaoshuidi.cloud.module.contract.service.contract.CustomerCompanyService;
import com.xiaoshuidi.cloud.module.contract.service.roommate.ContractRoommateService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.xiaoshuidi.cloud.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.xiaoshuidi.cloud.module.contract.enums.ApiConstants.*;
import static com.xiaoshuidi.cloud.module.contract.enums.ErrorCodeConstants.*;

/**
 * 企业客户 Service 实现类
 *
 * @author 合房租赁
 */
@Service
@Slf4j
public class CustomerCompanyServiceImpl implements CustomerCompanyService {

    @Resource
    private CustomerCompanyMapper customerCompanyMapper;

    @Lazy
    @Resource
    private CompanyContractService companyContractService;

    @Lazy
    @Resource
    private ContractRoomService contractRoomService;

    @Resource
    private ContractRoomMapper contractRoomMapper;

    @Lazy
    @Resource
    private ContractRoommateService contractRoommateService;

    @Resource
    private RentOrderMapper rentOrderMapper;

    @Override
    public Long createCustomerCompany(CustomerCompanyCreateReqVO createReqVO) {
        // 插入
        CustomerCompanyDO customerCompany = CustomerCompanyConvert.INSTANCE.convert(createReqVO);
        // 证件数量校验
        List<String> documentList = customerCompany.getDocumentList();
        if (CollectionUtils.isNotEmpty(documentList) && documentList.size() > THREE){
            throw exception(CUSTOMER_COMPANY_DOCUMENT_LIMIT);
        }
        // 校验企业名称是否重复
        valiateCompanyName(customerCompany.getCompanyName(), null);
        customerCompanyMapper.insert(customerCompany);
        // 返回
        return customerCompany.getId();
    }

    /**
     * 校验企业名称是否重复
     */
    private void valiateCompanyName(String companyName, Long id){
        LambdaQueryWrapper<CustomerCompanyDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.ne(Objects.nonNull(id), CustomerCompanyDO::getId, id);
        queryWrapper.eq(CustomerCompanyDO::getCompanyName, companyName);
        List<CustomerCompanyDO> customerCompanyList = customerCompanyMapper.selectList(queryWrapper);
        if (CollectionUtils.isNotEmpty(customerCompanyList)){
            throw exception(CUSTOMER_COMPANY_NAME_REPEAT);
        }
    }

    @Override
    public void updateCustomerCompany(CustomerCompanyUpdateReqVO updateReqVO) {
        // 校验存在
        validateCustomerCompanyExists(updateReqVO.getId());
        // 更新
        CustomerCompanyDO updateObj = CustomerCompanyConvert.INSTANCE.convert(updateReqVO);
        //证件图片
        if (CollectionUtils.isEmpty(updateReqVO.getDocumentList())){
            updateObj.setDocumentList(null);
        }else {
            // 证件数量校验
            if (updateReqVO.getDocumentList().size() > THREE){
                throw exception(CUSTOMER_COMPANY_DOCUMENT_LIMIT);
            }
        }
        // 校验企业名称是否重复
        valiateCompanyName(updateReqVO.getCompanyName(), updateReqVO.getId());
        customerCompanyMapper.updateById(updateObj);
        //修改企业合同的联系人手机号码
        contractRoomMapper.updatePhoneByCustomerCompanyId(updateObj.getContactsName(),updateObj.getContactsPhone(),updateObj.getAgentPhone(),updateObj.getId());
    }

    @Override
    public void deleteCustomerCompany(Long id) {
        // 校验存在
        validateCustomerCompanyExists(id);
        // 校验企业客户是否有签约数据
        CompanyContractStatusListRespVO companyContractSimpleList = companyContractService.getCompanyContractSimpleList(id);
        if (Objects.nonNull(companyContractSimpleList) &&
                (CollectionUtils.isNotEmpty(companyContractSimpleList.getPendingData())
                        || CollectionUtils.isNotEmpty(companyContractSimpleList.getActiveData())
                        || CollectionUtils.isNotEmpty(companyContractSimpleList.getRenewalData()))){
            // 存在审批中、生效中、续租合同无法删除
            throw exception(CUSTOMER_COMPANY_EXIST_REF_CONTRACT);
        }
        // 删除
        customerCompanyMapper.deleteById(id);
    }

    private CustomerCompanyDO validateCustomerCompanyExists(Long id) {
        CustomerCompanyDO companyDO = customerCompanyMapper.selectById(id);
        if (companyDO == null) {
            throw exception(CUSTOMER_COMPANY_NOT_EXISTS);
        }
        return companyDO;
    }

    @Override
    public CustomerCompanyRespVO getCustomerCompany(Long id) {
        CustomerCompanyDO customerCompanyDO = customerCompanyMapper.selectById(id);
        CustomerCompanyRespVO companyRespVO = CustomerCompanyConvert.INSTANCE.convert(customerCompanyDO);
        return companyRespVO;
    }

    @Override
    public List<CustomerCompanyDO> getCustomerCompanyList(Collection<Long> ids) {
        return CollectionUtils.isEmpty(ids) ? Collections.emptyList() : customerCompanyMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<CustomerCompanyDO> getCustomerCompanyPage(CustomerCompanyPageReqVO pageReqVO) {
        Page<CustomerCompanyDO> page = new Page<>(pageReqVO.getPageNo(),pageReqVO.getPageSize());
        LambdaQueryWrapper<CustomerCompanyDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(pageReqVO.getCompanyName()),CustomerCompanyDO::getCompanyName, pageReqVO.getCompanyName());
        queryWrapper.ge(Objects.nonNull(pageReqVO.getStartTime()), CustomerCompanyDO::getCreateTime, Objects.nonNull(pageReqVO.getStartTime())?pageReqVO.getStartTime().atStartOfDay():"");
        queryWrapper.lt(Objects.nonNull(pageReqVO.getEndTime()), CustomerCompanyDO::getCreateTime, Objects.nonNull(pageReqVO.getEndTime())?pageReqVO.getEndTime().plusDays(ONE).atStartOfDay():"");
        queryWrapper.orderByDesc(CustomerCompanyDO::getUpdateTime);
        page = customerCompanyMapper.selectPage(page, queryWrapper);
        PageResult<CustomerCompanyDO> pageResult = new PageResult<>(page.getRecords(),  page.getTotal());
        return pageResult;
    }

    @Override
    public CustomerCompanyDO getCompanyDoById(Long id) {
        if (Objects.isNull(id)){
            return null;
        }
        return customerCompanyMapper.selectById(id);
    }

    @Override
    public PageResult<CompanyRentRoomRespVO> getCompanyRentRoomPage(CompanyRentRoomPageReqVO pageVO) {
        PageHelper.startPage(pageVO.getPageNo(),pageVO.getPageSize());
        List<ContractRoomDO> companyContractList = null;
        ContractRoomStatusQueryReqVO statusQueryReq = new ContractRoomStatusQueryReqVO();
        statusQueryReq.setCustomerContractId(pageVO.getCompanyId());
        statusQueryReq.setRoomName(pageVO.getRoomName());
        if (ZERO.intValue() == pageVO.getType()){
            // 在租房间
            // 合同状态:已生效 入住    合同节点:除退租
            statusQueryReq.setContractStatusList(Arrays.asList(ContractStatusEnum.ACTIVE.getCode(), ContractStatusEnum.CHECK_IN.getCode()));
            statusQueryReq.setContractNodeWithoutList(Arrays.asList(ContractNodeEnum.RENTING_OUT.getCode()));
            companyContractList = contractRoomService.getContractByStatus(statusQueryReq);
        }else if (ONE.intValue() == pageVO.getType()){
            // 退租房间
            // 合同节点：退租
            statusQueryReq.setContractNode(ContractNodeEnum.RENTING_OUT.getCode());
            companyContractList = contractRoomService.getContractByStatus(statusQueryReq);
        }
        if (CollectionUtils.isEmpty(companyContractList)){
            return null;
        }
        PageInfo<ContractRoomDO> pageInfo = new PageInfo(companyContractList);
        List<ContractRoomDO> list = pageInfo.getList();
        List<CompanyRentRoomRespVO> resultList = new ArrayList<>();
        for (ContractRoomDO contractRoom : list) {
            CompanyRentRoomRespVO rentRoomResp = CustomerCompanyConvert.INSTANCE.convert(contractRoom);
            rentRoomResp.setContractNo(contractRoom.getContractNo());
            rentRoomResp.setCompanyId(pageVO.getCompanyId());
            // 入住人数
            List<ContractRoommateDO> roommateList = contractRoommateService.getRoommateList(contractRoom.getId());
            if (CollectionUtils.isNotEmpty(roommateList)){
                rentRoomResp.setCurrentLivingNum(roommateList.size());
            }
            // 水电承担方
            if (CompanyContractOrderShareTypeEnum.ALL.getCode().equals(contractRoom.getOrderShareMethod())){
                rentRoomResp.setHydropowerProvider(HYDROPOWER_PROVIDER_COMPANY);
            } else if (CompanyContractOrderShareTypeEnum.RENT_DEPOSIT_ONLY_WITH_PERSONAL.getCode().equals(contractRoom.getOrderShareMethod())){
                rentRoomResp.setHydropowerProvider(HYDROPOWER_PROVIDER_ROOM_CHIEF);
            } else if (CompanyContractOrderShareTypeEnum.RENT_DEPOSIT_ONLY_WITH_ROOM.getCode().equals(contractRoom.getOrderShareMethod())) {
                rentRoomResp.setHydropowerProvider("同住人共同承担");
            }
            // 退租房间 处理状态字段
            if (ONE.intValue() == pageVO.getType()){
                List<String> endStatusList = Arrays.asList(ContractStatusEnum.NORMAL_END.getCode(), ContractStatusEnum.ABNORMAL_END.getCode());
                if (endStatusList.contains(contractRoom.getContractStatus())){
                    rentRoomResp.setStatus(ROOM_STATUS_RENTED);
                }else if (ContractStatusEnum.PENDING.getCode().equals(contractRoom.getApproveStatus())){
                    rentRoomResp.setStatus(ROOM_STATUS_APPROVAL);
                }else if (ContractStatusEnum.REJECT.getCode().equals(contractRoom.getApproveStatus())){
                    rentRoomResp.setStatus(ROOM_STATUS_REJECT);
                }
            }
            // 房源名称
            resultList.add(rentRoomResp);
        }

        return new PageResult<>(resultList, pageInfo.getTotal());
    }


    @Override
    public void changeHydropowerTenantry(CompanyChangeUndertakerReqVO reqVO) {
        LambdaUpdateWrapper<ContractRoomDO> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(ContractRoomDO::getId, reqVO.getContractId());
        updateWrapper.set(ContractRoomDO::getOrderShareMethod, reqVO.getHydropowerUndertaker());
        contractRoomMapper.update(null, updateWrapper);

        // 修改未付款账单的member_id
        LambdaUpdateWrapper<RentOrderDO> rentOrderUpdateWrapper = new LambdaUpdateWrapper<>();
        rentOrderUpdateWrapper.eq(RentOrderDO::getOrderType, OrderTypeEnum.METER.getCode());
        rentOrderUpdateWrapper.eq(RentOrderDO::getBusinessId, reqVO.getContractId());
        List<String> payStatusList = Arrays.asList(OrderPayStatusEnum.UNPAID.getCode(), OrderPayStatusEnum.PART.getCode());
        rentOrderUpdateWrapper.in(RentOrderDO::getPayStatus, payStatusList);
        if (CompanyContractOrderShareTypeEnum.ALL.getCode().equals(reqVO.getHydropowerUndertaker())){
            // 企业承担
            rentOrderUpdateWrapper.set(RentOrderDO::getMemberId, null);
        } else if (CompanyContractOrderShareTypeEnum.RENT_DEPOSIT_ONLY_WITH_PERSONAL.getCode().equals(reqVO.getHydropowerUndertaker())) {
            // 个人承担
            // 查询房间寝室长
            ContractRoommateDO param = new ContractRoommateDO();
            param.setRoomContractId(reqVO.getContractId());
            param.setRoommateType(RoommateTypeEnum.LESSESS.getCode());
            List<ContractRoommateDO> byParam = contractRoommateService.getByParam(param);
            if (CollectionUtils.isEmpty(byParam)){
                log.error("切换水电承租方，未查询到寝室长信息，切换水电承租方参数：{}", JSONObject.toJSONString(reqVO));
                return;
            }
            ContractRoommateDO roommateDO = byParam.get(0);
            if (Objects.nonNull(roommateDO.getMemberId())){
                log.error("切换水电承租方，未查询到寝室长会员编号信息，切换水电承租方参数：{}，寝室长信息：{}", JSONObject.toJSONString(reqVO), JSONObject.toJSONString(roommateDO));
                return;
            }
            rentOrderUpdateWrapper.set(RentOrderDO::getMemberId, roommateDO.getMemberId());
        } else if (CompanyContractOrderShareTypeEnum.RENT_DEPOSIT_ONLY_WITH_ROOM.getCode().equals(reqVO.getHydropowerUndertaker())) {
            log.info("切换水电承担方式到房屋; {}", JsonUtils.toJsonString(reqVO));
            rentOrderUpdateWrapper.set(RentOrderDO::getMemberId, null);
        }
        rentOrderMapper.update(null, rentOrderUpdateWrapper);

    }


    @Override
    public void disabledCustomerCompany(Long id) {
        CustomerCompanyDO companyDO = validateCustomerCompanyExists(id);
        if (ZERO.intValue() == companyDO.getDisableFlag()){
            companyDO.setDisableFlag(ONE);
        }else if (ONE.intValue() == companyDO.getDisableFlag()){
            companyDO.setDisableFlag(ZERO);
        }
        customerCompanyMapper.updateById(companyDO);
    }
}
